package org.jks.service;

import java.io.Serializable;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate4.support.HibernateDaoSupport;
import org.springframework.transaction.annotation.Transactional;

public class BaseDaoImpl<T> extends HibernateDaoSupport implements IBaseDao<T> {
	public SessionFactory sessionFactory;
	@Resource
	public void setSessionFacotry(SessionFactory sessionFacotry) {
		super.setSessionFactory(sessionFacotry);
		this.sessionFactory = sessionFacotry;
	}
	
	public Session openSession(){
		return sessionFactory.openSession();
	}
	
	public Serializable save(List<T> list) {
		Session session = this.openSession();
		Serializable obj = null;
		
		try{
			session.getTransaction().begin();
			for(T o : list){
				obj = session.save(o);
			}
			session.getTransaction().commit();
		}
		catch(Exception e){
			session.getTransaction().rollback();
		}
		session.flush();
		session.close();
		
		return obj;
	}

	public Serializable save(T o) {
		Session session = this.openSession();
		Serializable obj = null;
		try{
			obj = session.save(o);
		}
		catch(Exception e){
			
		}
		session.flush();
		session.close();
		return obj;
	}

	@Transactional
	public void delete(T o) {
		Session session = this.openSession();
		try{
			session.delete(o);
		}
		catch(Exception e){}
		session.flush();
		session.close();
	}

	@Transactional
	public void update(T o) {
		Session session = this.openSession();
		try{
			session.update(o);
		}
		catch(Exception e){}
		session.flush();
		session.close();
	}
	
	public void update(List<T> list) {
		Session session = this.openSession();
		try{
			session.getTransaction().begin();
			for(T o : list){
				session.update(o);
			}
			session.getTransaction().commit();
		}
		catch(Exception e){
			session.getTransaction().rollback();
		}
		session.flush();
		session.close();
	}

	public void saveOrUpdate(T o) {
		Session session = this.openSession();
		try{
			session.saveOrUpdate(o);
			
		}
		catch(Exception e){
			
		}
		session.flush();
		session.close();
	}

	@SuppressWarnings("unchecked")
	public List<T> find(String hql) {
		Session session = this.openSession();
		List<T> out = null;
		try{
			out = session.createQuery(hql).list();
		}
		catch(Exception e){}
		session.close();
		return out;
	}

	@SuppressWarnings("unchecked")
	public List<T> find(String hql, Object[] param) {
		Session session = this.openSession();
		Query q = session.createQuery(hql);
		if (param != null && param.length > 0) {
			for (int i = 0; i < param.length; i++) {
				q.setParameter(i, param[i]);
			}
		}
		List<T> out = null;
		try{
			out = q.list();
		}
		catch(Exception e){}

		session.close();
		return out;
	}

	@SuppressWarnings("unchecked")
	public List<T> find(String hql, List<Object> param) {
		Session session = this.openSession();
		Query q = session.createQuery(hql);
		if (param != null && param.size() > 0) {
			for (int i = 0; i < param.size(); i++) {
				q.setParameter(i, param.get(i));
			}
		}
		List<T> out = null;
		try{
			out = q.list();
		}
		catch(Exception e){
			
		}
		session.close();
		return out;
	}

	@SuppressWarnings("unchecked")
	public List<T> find(String hql, Object[] param, Integer page, Integer rows) {
		if (page == null || page < 1) {
			page = 1;
		}
		if (rows == null || rows < 1) {
			rows = 10;
		}
		Session session = this.openSession();
		Query q = session.createQuery(hql);

		if (param != null && param.length > 0) {
			for (int i = 0; i < param.length; i++) {
				q.setParameter(i, param[i]);
			}
		}
		List<T> out = null;
		try{
			out = q.setFirstResult((page - 1) * rows).setMaxResults(rows).list();
		}
		catch(Exception e){}
		session.close();
		return out;
	}

	@SuppressWarnings("unchecked")
	public List<T> find(String hql, List<Object> param, Integer page,
			Integer rows) {
		if (page == null || page < 1) {
			page = 1;
		}
		if (rows == null || rows < 1) {
			rows = 10;
		}
		Session session = this.openSession();
		Query q = session.createQuery(hql);
		if (param != null && param.size() > 0) {
			for (int i = 0; i < param.size(); i++) {
				q.setParameter(i, param.get(i));
			}
		}
		List<T> out = null;
		try{
			out = q.setFirstResult((page - 1) * rows).setMaxResults(rows).list();
		}
		catch(Exception e){}
		session.close();
		return out;
	}

	@SuppressWarnings("unchecked")
	public T get(Class<T> c, Serializable id) {
		Session session = this.openSession();
		T out = null;
		try{
			out = (T) session.get(c, id);
		}
		catch(Exception e){}
		session.close();
		return out;
	}

	public T get(String hql, Object[] param) {
		List<T> l = this.find(hql, param);
		if (l != null && l.size() > 0) {
			T out = l.get(0);
			if(out != null){
				if(!Hibernate.isInitialized(out))   
					Hibernate.initialize(out); 
				
			}
			return out;
		} else {
			return null;
		}
	}

	public T get(String hql, List<Object> param) {
		List<T> l = this.find(hql, param);
		if (l != null && l.size() > 0) {
			T out = l.get(0);
			if(out != null){
				if(!Hibernate.isInitialized(out))   
					Hibernate.initialize(out); 
				
			}
			return out;
		} else {
			return null;
		}
	}

	public long count(String hql) {
		Session session = this.openSession();
		long count = 0;
		try{
			Object o = session.createQuery(hql).uniqueResult();
			count = Long.valueOf(String.valueOf(o)).longValue(); 
		}
		catch(Exception e){
			e.printStackTrace();
		}
		
		session.close();
		return count;
	}

	public long count(String hql, Object[] param) {
		Session session = this.openSession();
		Query q = session.createQuery(hql);
		if (param != null && param.length > 0) {
			for (int i = 0; i < param.length; i++) {
				q.setParameter(i, param[i]);
			}
		}
		long count = 0;
		try{
			count = (Long) q.uniqueResult();
		}
		catch(Exception e){}
		session.close();
		return count;
	}

	public long count(String hql, List<Object> param) {
		Session session = this.openSession();
		Query q = session.createQuery(hql);
		if (param != null && param.size() > 0) {
			for (int i = 0; i < param.size(); i++) {
				q.setParameter(i, param.get(i));
			}
		}
		long count = 0;
		try{
			count = (Long) q.uniqueResult();
		}
		catch(Exception e){}
		
		session.close();
		return count;
	}

	public int executeHql(String hql) {
		Session session = this.openSession();
		int count = 0;
		try{
			count = session.createQuery(hql).executeUpdate();
		}
		catch(Exception e){}
		
		session.close();
		return count;
	}

	public int executeHql(String hql, Object[] param) {
		Session session = this.openSession();
		Query q = session.createQuery(hql);
		if (param != null && param.length > 0) {
			for (int i = 0; i < param.length; i++) {
				q.setParameter(i, param[i]);
			}
		}
		int count = 0;
		try{
			count = q.executeUpdate();
		}
		catch(Exception e){}
		session.close();
		return count;
	}

	public int executeHql(String hql, List<Object> param) {
		Session session = this.openSession();
		Query q = session.createQuery(hql);
		if (param != null && param.size() > 0) {
			for (int i = 0; i < param.size(); i++) {
				q.setParameter(i, param.get(i));
			}
		}
		int count = 0;
		try{
			count = q.executeUpdate();
		}
		catch(Exception e){}
		
		session.close();
		return count;
	}
	
	public T first(String hql){
		Session session = this.openSession();
		Query q = session.createQuery(hql);
		@SuppressWarnings("unchecked")
		T o = (T) q.uniqueResult();
		session.close();
		return o;
	}
}
